#include <iostream>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netinet/in.h>

#define BUFSIZE 100

struct tcp_data
{
    short command = 0;
    char data[40] = "holle client.";
};

int main(){
    int serv_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    struct sockaddr_in serv_addr;
    memset(&serv_addr, 0, sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
    serv_addr.sin_port = htons(55550);

    if(0 > bind(serv_sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr))){
        perror("bind failed!");
        return -1;
    }

    if(0 > listen(serv_sock, 20)){
        perror("listen failed !");
        return -1;
    }

    tcp_data data;
    char buff[BUFSIZE];
    data.command = 1;
    // mempcpy(data.data, "holle client.", 14);
    struct sockaddr_in clnt_addr;
    socklen_t caddr_size = sizeof(clnt_addr);
    int clnt_sock = accept(serv_sock, (struct sockaddr *)&clnt_addr, &caddr_size);
    if(0 > clnt_sock){
        perror("accept failed .");
        return -1;
    }else{
        std::cout << "accept client ." << std::endl;
        std::cout << "connected." << std::endl;
    }
    while(true){
        if(0 > read(clnt_sock, buff, sizeof(buff)-1)){
            perror("read error!");
            continue;
        }else{
            if(0 == data.command){
                break;
            }
            memcpy(&data, buff, sizeof(data));
            std::cout << "command : " << data.command << std::endl;
            std::cout << "data : " << data.data << std::endl << std::endl;
            strcpy(data.data, "server received!");
            memcpy(buff, &data, sizeof(data));

            if(0 > write(clnt_sock, buff, sizeof(data))){
                perror("write failed !");
                continue;
            }
        }
    }
    close(clnt_sock);
    close(serv_sock);
}